package com.xjscrm.console.service.customer.chat.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.uzai.mobile.collect.api.dto.trigger.talk.MicaTalkContentTextMsg;
import com.uzai.mobile.collect.api.enums.MicaTalkMsgType;
import com.xjscrm.common.annotation.MerId;
import com.xjscrm.console.chat.cache.CacheHolder;
import com.xjscrm.console.chat.enums.ChatTalkRecordSendStatus;
import com.xjscrm.console.chat.enums.ChatTalkRecordSource;
import com.xjscrm.console.chat.enums.MQMsgType;
import com.xjscrm.console.chat.frame.send.SRecallSuccessMsg;
import com.xjscrm.console.chat.mq.MQSender;
import com.xjscrm.console.chat.mq.dto.SendMQDTO;
import com.xjscrm.console.chat.utils.MessageUtil;
import com.xjscrm.console.dto.chat.ChatTalkRecordQueryDTO;
import com.xjscrm.console.entity.ChatTalkRecord;
import com.xjscrm.console.entity.ChatTalkSession;
import com.xjscrm.console.entity.ChatTalkSessionStaffRel;
import com.xjscrm.console.mapper.ChatTalkRecordMapper;
import com.xjscrm.console.mapper.ChatTalkSessionStaffRelMapper;
import com.xjscrm.console.service.customer.chat.ChatTalkRecordService;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.xjscrm.console.chat.core.impl.ChatRecallMsgHandler.RECALL_KEY;

/**
 * 聊天记录(ChatTalkRecord)表服务实现类
 *
 * @author szl
 * @since 2024-03-12 13:36:00
 */
@Service
@Slf4j
public class ChatTalkRecordServiceImpl implements ChatTalkRecordService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private CacheHolder cacheHolder;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ChatTalkRecordMapper chatTalkRecordMapper;
    @Autowired
    private ChatTalkSessionStaffRelMapper chatTalkSessionStaffRelMapper;

    @Override
    public ChatTalkRecord loadLastTalk(ChatTalkRecordQueryDTO query) {
        return chatTalkRecordMapper.selectByPrimaryKey(query.getId());
    }

    @Override
    public void add(ChatTalkRecord chatTalkRecord) {
        this.chatTalkRecordMapper.insertSelective(chatTalkRecord);

        // todo 设置相关的缓存
    }

    @Override
    public ChatTalkRecord getById(ChatTalkRecordQueryDTO chatTalkRecordQuery) {

        List<ChatTalkRecord> select = this.chatTalkRecordMapper.select(chatTalkRecordQuery);
        if (ObjectUtils.isNotEmpty(select)) {
            return select.get(0);
        }
        return null;
    }

    @Override
    public ChatTalkRecord getById(@MerId Long merId, Long id) {
        return chatTalkRecordMapper.selectByPrimaryKey(id);
    }

    @Override
    public ChatTalkRecord getById(@MerId Long merId, Long id, Long talkSessionId) {
        ChatTalkRecord chatTalkRecord = new ChatTalkRecord();
        chatTalkRecord.setMerId(merId);
        chatTalkRecord.setId(id);
        chatTalkRecord.setTalkSessionId(talkSessionId);

        return chatTalkRecordMapper.selectOne(chatTalkRecord);
    }

    @Override
    public List<ChatTalkRecord> listByIds(@MerId Long merId, List<Long> ids, Long talkSessionId) {
        return chatTalkRecordMapper.selectList(merId, ids, talkSessionId);
    }

    @Override
    public void updateById(ChatTalkRecord byId) {
        chatTalkRecordMapper.updateByPrimaryKeySelective(byId);
    }

    @Override
    public List<ChatTalkRecord> listByTime(ChatTalkRecordQueryDTO query) {
        return this.chatTalkRecordMapper.select(query);
    }

    @Override
    public Integer countWithNoRead(@MerId Long merId, Long talkSessionId, Integer lastReadTime) {

        return chatTalkRecordMapper.countWithNoRead(merId, talkSessionId, lastReadTime);
    }

    @Override
    public ChatTalkRecord buildTextRecord(@MerId Long merId, Long staffId, ChatTalkSession talkSession, String text) {
        int currentTime = (int) (System.currentTimeMillis() / 1000L);
        ChatTalkRecord record = new ChatTalkRecord();
        record.setId(IdUtil.getSnowflakeNextId());
        record.setMerId(merId);
        record.setDeviceUniqueId(talkSession.getDeviceUniqueId());
        record.setTalkSessionId(talkSession.getId());
        record.setConversationId(talkSession.getConversationId());
        record.setContentType(MicaTalkMsgType.TEXT.getCode());
        record.setSource(ChatTalkRecordSource.reply.getCode());
        record.setSendTime(currentTime);
        MicaTalkContentTextMsg textMsg = new MicaTalkContentTextMsg();
        textMsg.setText(text);
        record.setContent(JSON.toJSONString(textMsg));
        record.setSendStatus(ChatTalkRecordSendStatus.sending.getCode());
        record.setCreateTime(currentTime);
        record.setCreateBy(staffId);
        chatTalkRecordMapper.insertSelective(record);
        return record;
    }

    @Override
    public void cleanChatTalkRecord(Long merId) {
        int now = (int) (System.currentTimeMillis() / 1000L);
        int before3DayTimeSecond = now - 60 * 60 * 24 * 3;
        chatTalkRecordMapper.deleteWithTime(merId, before3DayTimeSecond);
    }

    @Override
    public void deleteOfRecallIfAbsent(@MerId Long merId, Long recordId) {
        String cacheKey = String.format(RECALL_KEY, recordId);
        if (Boolean.FALSE.equals(redisTemplate.hasKey(cacheKey))) {
            return;
        }
        chatTalkRecordMapper.updateRecall(recordId);
        redisTemplate.expire(cacheKey, 0, TimeUnit.MILLISECONDS);

        ChatTalkRecord chatTalkRecord = chatTalkRecordMapper.selectByPrimaryKey(recordId);
        if (Objects.isNull(chatTalkRecord)) {
            return;
        }
        Long talkSessionId = chatTalkRecord.getTalkSessionId();

        ChatTalkSessionStaffRel talkSessionStaffRel = chatTalkSessionStaffRelMapper.selectOneBySessionId(merId, chatTalkRecord.getDeviceUniqueId(), talkSessionId);
        if (Objects.isNull(talkSessionStaffRel)) {
            return;
        }
        Long staffId = talkSessionStaffRel.getStaffId();
        Channel staffChannel = cacheHolder.getStaffChannel(staffId);
        if (Objects.nonNull(staffChannel)) {
            SRecallSuccessMsg sRecallSuccessMsg = new SRecallSuccessMsg(recordId, talkSessionId);
            MessageUtil.sendMsg(staffChannel, sRecallSuccessMsg);
            return;
        }
        SRecallSuccessMsg sRecallSuccessMsg = new SRecallSuccessMsg(recordId, talkSessionId);
        sRecallSuccessMsg.setStaffId(staffId);
        SendMQDTO sendMQDTO = new SendMQDTO();
        sendMQDTO.setType(MQMsgType.recall_success.getCode());
        sendMQDTO.setData(sRecallSuccessMsg);

        String staffTag = cacheHolder.getStaffTag(staffId);

        MQSender.sendMQMsg("XJ_WW_DISPATCH_HANDLE_TOPIC:" + staffTag, sendMQDTO);
    }

    @Override
    public ChatTalkRecord getLastTalk(@MerId Long merId, Long deviceUniqueId, Long sessionId) {
        return chatTalkRecordMapper.selectLastByDeviceUniqueIdAndSessionId(merId, deviceUniqueId, sessionId);
    }
}

